package com.mjp.learn.multi.juc;



import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * CyclicBarrier
 * 可以理解为循环栅栏
 * cyclicBarrier await 是指的等待所有的线程都完成任务
 */
public class Demo06 {

    public static class Solider implements Runnable {

        private String solider;

        private final CyclicBarrier cyclicBarrier;

        public Solider(CyclicBarrier cyclicBarrier, String solider) {
            this.solider = solider;
            this.cyclicBarrier = cyclicBarrier;
        }

        @Override
        public void run() {
            try {
                //等待所有士兵都到齐
                cyclicBarrier.await();
                doWork();
                //等待所有士兵完成工作
                cyclicBarrier.await();
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
        }

        void doWork() {
            try {
                Thread.sleep(Math.abs(new Random().nextInt() % 10000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(solider + ":任务完成");
        }
    }


    public static class BarrierRun implements Runnable {

        Boolean flag;

        Integer N;


        public BarrierRun(boolean flag, int N) {
            this.flag = flag;
            this.N = N;
        }

        @Override
        public void run() {
            if (flag) {
                System.out.println("司令:[士兵" + N + "个,任务完成!]");
            } else {
                System.out.println("司令:[士兵" + N + "个,集合完毕!]");
                flag = true;
            }
        }
    }

    public static void main(String[] args) {
        final int N = 10;
        Thread[] allSoldier = new Thread[N];
        CyclicBarrier cyclicBarrier = new CyclicBarrier(N, new BarrierRun(false, N));
        System.out.println("集合队伍!");

        for (int i = 0; i < N; i++) {
            System.out.println("士兵 " + i + " 报道!");
            allSoldier[i] = new Thread(new Solider(cyclicBarrier, "士兵" + i));
            allSoldier[i].start();
        }
    }
}
